package com.kn.keywordmatch.service.impl;


import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONUtil;
import com.kn.keywordmatch.common.IndexRotator;
import com.kn.keywordmatch.common.RabbitMqCon;
import com.kn.keywordmatch.dto.req.MatchByKeywordReq;
import com.kn.keywordmatch.dto.req.MatchDistanceReq;
import com.kn.keywordmatch.dto.resp.BaseResp;
import com.kn.keywordmatch.dto.resp.MatchDistanceResp;
import com.kn.keywordmatch.dto.resp.ParseKeywordExpressionResp;
import com.kn.keywordmatch.dto.resp.PlanManagesItem;
import com.kn.keywordmatch.service.KeywordIndex;
import com.kn.keywordmatch.service.MatchService;
import lombok.extern.slf4j.Slf4j;
import org.ahocorasick.trie.Emit;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MatchServiceImpl implements MatchService {

    @Autowired
    @Qualifier("redisTemplateWithString")
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private KeywordIndex keywordIndex;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    /*
       * 表达式规则：
1           |或+不能连续使用，正确：A|B,A+B，错误：A||B,A++B,A+|B
2           +|不能存在同一层级，正确：A+(B|C),(A|B)+C，错误：A+B|C,(A|B+C)
3           括号必须成组使用，正确：A+(B|C),错误：(A|B+C
            括号不能嵌套使用，正确：A+(B|C)+D,错误：(A+(B|C))+D
5           长度限制1000字符
6,          去掉括号之后连续的+号不能超过五个
*           |或+不能作为开头和结尾，即前后必须得有元素，正确：A|B,A+B，错误：|B,A+
*
* 7        括号内  |或+也不能作为开头和结尾，，正确：A|(B+C)，错误：A|(B+)
8        括号中必须有元素，不能为空，正确：A+(B|C)，错误：（）
* 9        括号不能连续使用，正确：(A+B)|(A+B)，错误：(A+B)(A+B)
       * */
    @Override
    public BaseResp<String> verifyKeywordExpression(String expression) {
        try {
            // 去掉空格
            expression = expression.replaceAll("\\s+", "");
            expression = expression.replace("）",")")
                    .replace("（","(")
                    .replace("｜","|");
            if(expression.contains("(") || expression.contains(")")){
                 if(expression.startsWith("(") && expression.endsWith(")") && replaceInnerContentsWithPlaceholder(expression).length() == 1){
                     expression = expression.replace("(","").replace(")","");
                    // 走基础校验
                    if (basicValidation(expression)) {
                        return new BaseResp(HttpStatus.HTTP_INTERNAL_ERROR, null, "表达式规则校验失败（基础表达式不合法）");
                    }
                 }else {
                     // 校验括号合法
                     if (hasNestedParentheses(expression) || hasBalancedParentheses(expression)
                             || hasEmpty(expression) || hasConsecutiveParentheses(expression)) {
                         return new BaseResp(HttpStatus.HTTP_INTERNAL_ERROR, null, "表达式规则校验失败（括号不合法)");

                     }
                     // 第一步：提取并校验每个括号内的内容
                     List<String> innerContents = extractInnerContents(expression);
                     for (String content : innerContents) {
                         if (basicValidation(content)) {
                             return new BaseResp(HttpStatus.HTTP_INTERNAL_ERROR, null, "表达式规则校验失败（括号内内容不合法）: " + content);
                         }
                     }

                     // 第二步：替换括号内的内容为任意字符并进行整体校验
                     String modifiedExpression = replaceInnerContentsWithPlaceholder(expression);
                     if (overallValidation(modifiedExpression)) {
                         return new BaseResp(HttpStatus.HTTP_INTERNAL_ERROR, null, "表达式规则校验失败（整体表达式不合法）");
                     }
                 }
            }else{
                // 走基础校验
                if (basicValidation(expression) || exceedsConsecutive(expression)) {
                    return new BaseResp(HttpStatus.HTTP_INTERNAL_ERROR, null, "表达式规则校验失败（基础表达式不合法）");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("MatchServiceImpl.verifyKeywordExpression【校验关键字表达式失败：{}】异常：{}",expression,e.getMessage());
        }

        return new BaseResp(HttpStatus.HTTP_OK, null, "表达式校验成功");
    }

    // 提取每个括号内的内容
    private List<String> extractInnerContents(String expression) {
        List<String> contents = new ArrayList<>();
        Stack<Integer> stack = new Stack<>();

        for (int i = 0; i < expression.length(); i++) {
            char ch = expression.charAt(i);
            if (ch == '(') {
                stack.push(i);
            } else if (ch == ')') {
                if (!stack.isEmpty()) {
                    int start = stack.pop();
                    contents.add(expression.substring(start + 1, i).trim());
                }
            }
        }
        return contents;
    }

    // 对单个内容进行基础校验
    private boolean basicValidation(String content) {
        if (hasConsecutiveOperators(content) || hasSameLevelOperators(content) || hasStartOrEnd(content)) {
            return true;
        }
        return false;
    }

    // 没有括号校验 连续+超过5个
    private static boolean exceedsConsecutive(String expression) {

        // 通过+分割
        String[] subParts = expression.split("\\s*\\+\\s*");
        if(subParts.length > 5){return true;}
        return false; // 不超过五个连续的+

    }
    // 替换括号内的内容为任意字符（例如用 "X" 替代）
    private static String replaceInnerContentsWithPlaceholder(String expression) {
        return expression.replaceAll("\\(.*?\\)", "X");
    }

    public static void main(String[] args) {
        String ex = "(张跃斌|蔡富强|唐建明|何彩玲|唐亚|李华林|张超|陈守文|石婧|胡华林|龚建华|廖卫平|刘晓萍|曹志远|周明冬|段宁洪|潘艳超|伍希志)";
        if(ex.startsWith("(") && ex.endsWith(")") ) {
            System.out.println(replaceInnerContentsWithPlaceholder(ex));
        }
    }
    // 进行整体校验
    private boolean overallValidation(String expression) {
        if (!expression.contains("|") && !expression.contains("+")) {
            return true;
        }
        if (basicValidation(expression) || exceedsConsecutivePlus(expression)) {
            return true;
        }
        return false;
    }



    //-------------------------------基础校验-------------------------------------//
    // |或+连续使用
    private static boolean hasConsecutiveOperators(String expression) {
        return expression.matches(".*[\\+\\|]{2,}.*");
    }

    // |或+存在同一级
    private static boolean hasSameLevelOperators(String expression) {
        String REGEX = "\\([^()]*\\)|[^()]+";

        // 通过正则匹配层级
        Pattern pattern = Pattern.compile(REGEX);
        Matcher matcher = pattern.matcher(expression);

        while (matcher.find()) {
            String part = matcher.group();
            if (part.contains("+") && part.contains("|")) {
                return true; // 同一层级中出现了 + 和 |
            }
        }
        return false;
    }
    // |或+ 开头结尾
    public static boolean hasStartOrEnd(String expression) {
        // 检查整个表达式是否以 + 或 | 开头或结尾
        if (expression.startsWith("|") ||expression.startsWith("+")
                || expression.endsWith("|") ||expression.endsWith("+")) {
            return true;
        }
        return false;
    }


    //-------------------------------括号校验-------------------------------------//
    // 括号内必须有元素
    public static boolean hasEmpty(String expression) {
        // 去掉空格
        expression = expression.replaceAll("\\s+", "");

        // 正则表达式：匹配空括号的情况
        String regexEmptyParentheses = "\\(\\)";
        String regexOnlySpacesInParentheses = "\\(\\s*\\)";

        // 检查是否包含空括号或仅包含空格的括号
        return expression.matches(".*" + regexEmptyParentheses + ".*") ||
                expression.matches(".*" + regexOnlySpacesInParentheses + ".*");
    }
    //括号必须成组使用
    private static boolean hasBalancedParentheses(String expression) {
        int balance = 0;
        for (char c : expression.toCharArray()) {
            if (c == '(') balance++;
            if (c == ')') balance--;
            if (balance < 0) return true; // 如果右括号超出左括号
        }
        return balance != 0; // 必须相等
    }
    // 存在嵌套括号
    private static boolean hasNestedParentheses(String expression) {
        // 检查是否有嵌套括号
        int depth = 0;
        for (char c : expression.toCharArray()) {
            if (c == '(') {
                depth++;
                if (depth > 1) return true; // 超过一层嵌套
            }
            if (c == ')') {
                depth--;
            }
        }
        return false; // 没有嵌套
    }
    // 括号不能连续使用
    public static boolean hasConsecutiveParentheses(String expression) {
        // 去掉空格
        expression = expression.replaceAll("\\s+", "");

        // 正则表达式：匹配连续的括号情况
        String regexConsecutiveParentheses = "\\)[^|\\+]*(\\()";

        // 检查是否包含连续的括号
        return expression.matches(".*" + regexConsecutiveParentheses + ".*");
    }

    //-------------------------------整体校验-------------------------------------//
    // 连续+超过5个
    private static boolean exceedsConsecutivePlus(String expression) {

        // 通过|分割
        String[] parts = expression.split("\\|");

        for (String part : parts) {
            // 检查每个部分中的连续+号
            String[] subParts = part.split("\\s*\\+\\s*");
            if(subParts.length > 5){
                return true;
            }
        }
        return false; // 不超过五个连续的+

    }


    /**
     *  解析关键字表达式
     * @param expression
     * @return
     */
    @Override
    public BaseResp<ParseKeywordExpressionResp> analysisKeywordExpression(String expression,String msg) {
        try {
            BaseResp<String> verifyResp = verifyKeywordExpression(expression);
            if(verifyResp.getState() != 200){
                log.info("【关键字表达式校验失败{}】：{}",msg,expression);

                return new BaseResp<>(HttpStatus.HTTP_INTERNAL_ERROR,null,"表达式校验失败");
            }
            Set<Set<String>> andSets = new HashSet<>();
            Set<Set<String>> orSets = new HashSet<>();
            expression = expression.replace("）",")")
                    .replace("（","(")
                    .replace("｜","|");
            ParseKeywordExpressionResp parseKeywordExpressionResp = parseExpression(expression, andSets, orSets);
            return new BaseResp<>(HttpStatus.HTTP_OK,parseKeywordExpressionResp,"表达式解析成功");
        }catch (Exception e){
            e.printStackTrace();
            log.info("【关键字表达式解析失败{}】：{}",msg,expression);
            log.error("MatchServiceImpl.analysisKeywordExpression【关键字表达式解析失败：{}】,异常：{}",expression,e.getMessage());
            return new BaseResp<>(HttpStatus.HTTP_INTERNAL_ERROR,null,"表达式解析失败");

        }

    }



    public static ParseKeywordExpressionResp parseExpression(String expression, Set<Set<String>> andSets, Set<Set<String>>  orSets) {
        // 处理空格
        expression = expression.replaceAll("\\s+", "");
        // 没括号
        if (!expression.contains("(")) {
            if (expression.contains("+")) {
                String[] ands = expression.split("\\+");
                if (ands.length > 0) {
                    andSets.add(Arrays.stream(ands).collect(Collectors.toSet()));
                }
            } else if (expression.contains("|")) {
                String[] ors = expression.split("\\|");
                if (ors.length > 0) {
                    for (String or : ors) {
                        orSets.add(Collections.singleton(or));
                    }
                }
            }else {
                // 单个的
                andSets.add(new HashSet<>(Collections.singletonList(expression)));
            }
        } else {
            /*A+B+C+(d|e)  解析为  or关系为（A，B，C，d）or关系为（A，B，C，e）
                a|b|c|(A+B+C+D)  解析为or关系为a， or关系b ，or关系c， or关系A+B+C+D，
                (A+B+C+D)|(a+b+c+d)   解析为or关系 A+B+C+D， a+b+c+d
                (A|B|C|D)+(a|b|c|d) 解析为or关系 A a, A b,A c, A d, 然后B C D的组合

                第二种思路：
                先将括号内的替换为X，然后判断整体表达式是and 还是or的关系，
                全部用+连接则为and关系，全部用|连接则为or关系
                如果是and的关系,
                    先判断每组括号内的关联关系 将多个括号中全是+号相连的放在一起作为集合A，如果没有OR关系的集合 则全部放在andSets中 结束
                    如果有Or关系的集合B， 则需要排列组合集合A的全部元素和集合B的每个元素
                    如果有OR关系的集合C，也是一样需要组合，组合完成后作为一个set集合 放在orSets中 结束

                    举例说明：(A+B+C+D)+(a+b+c+d) 则应解析为 andSets：[[A,B,C,D],[a,b,c,d]],orSets:[]
                    (A+B+C+D)+(a|b|c|d) 则应解析为 orSets：[[A,B,C,D,a],[A,B,C,D,b][A,B,C,D,c][A,B,C,D,d],],andSets:[]
                    (A|B|C|D)+(a|b|c|d) 则应解析为 orSets：[[A,a],[A,b][A,c][A,d],[B,a],[B,b][B,c][B,d],
                    [C,a],[C,b][C,c][C,d],[D,a],[D,b][D,c][D,d]],andSets:[]
                    如果有其他集合，还需再次进行排列组合
                如果是Or的关系
                    先判断每组括号内的关联关系，将每组括号中有+号相连的，放在orSets中，每组为一个set，将括号中有|连接的每个元素 作为一个set放在orSets中，
                    将括号外的每个元素作为一个set放在orSets中
                    举例说明：
                    (A+B+C+D)|(a+b+c+d)|q|w|e|(g|e) 则应解析为 andSets：[],orSets:[[A,B,C,D],[a,b,c,d],[q],[w],[e]]
            */

            // 有括号的情况

            parseWithParentheses(expression, andSets, orSets);
        }
        ParseKeywordExpressionResp parseKeywordExpressionResp = new ParseKeywordExpressionResp();
        parseKeywordExpressionResp.setOrSets(orSets);
        parseKeywordExpressionResp.setAndSets(andSets);
        return parseKeywordExpressionResp;
    }

    public static void parseWithParentheses(String expression, Set<Set<String>> andSets, Set<Set<String>> orSets) {
        // 将括号内的内容替换为X，并且记录括号中的表达式
        Map<String, String> bracketContentMap = new HashMap<>();
        Stack<Integer> stack = new Stack<>();
        int bracketCounter = 1;

        StringBuilder expr = new StringBuilder(expression);
        for (int i = 0; i < expr.length(); i++) {
            if (expr.charAt(i) == '(') {
                stack.push(i);
            } else if (expr.charAt(i) == ')') {
                int start = stack.pop();
                String content = expr.substring(start + 1, i);
                String placeholder = "X" + bracketCounter++;
                bracketContentMap.put(placeholder, content);
                expr.replace(start, i + 1, placeholder);
                i = start + placeholder.length() - 1;
            }
        }

        // 判断整个表达式是 AND 还是 OR 的关系
        if (expr.indexOf("|") != -1) {
            // OR 的情况
            handleOrExpression(expr.toString(), bracketContentMap, orSets);
        } else if (expr.indexOf("+") != -1) {
            // AND 的情况
            handleAndExpression(expr.toString(), bracketContentMap, andSets, orSets);
        }
    }

    // 处理 OR 的表达式
    private static void handleOrExpression(String expr, Map<String, String> bracketContentMap, Set<Set<String>> orSets) {
        String[] orGroups = expr.split("\\|");
        for (String group : orGroups) {
            if (group.startsWith("X")) {
                String content = bracketContentMap.get(group);
                if (StrUtil.isNotBlank(content)) {
                    if (content.contains("|")) {
                        // 如果括号内是 OR 关系，直接分解括号内内容为 OR 集合
                        handleOrExpression(content, bracketContentMap, orSets);
                    } else if (content.contains("+")) {
                        // 如果括号内是 AND 关系，将括号内的内容作为整体加入 OR 集合
                        Set<String> set = new HashSet<>(Arrays.asList(content.split("\\+")));
                        orSets.add(set);
                    }else {
                        //单个的
                        orSets.add(new HashSet<>(Collections.singletonList(content)));
                    }
                }

            } else if (group.contains("+")) {
                // 处理 + 号连接的内容
                Set<String> set = new HashSet<>(Arrays.asList(group.split("\\+")));
                orSets.add(set);
            } else {
                // 单一元素
                orSets.add(Collections.singleton(group.trim()));
            }
        }
    }

    public static void generateCombinations(List<List<String>> groups, List<String> current, List<List<String>> results, int index) {
        // 递归基准条件：当索引达到最后一组时，将当前组合加入结果中
        if (index == groups.size()) {
            results.add(new ArrayList<>(current));
            return;
        }

        // 遍历当前组中的每个选项，并将其加入当前组合，递归处理下一组
        for (String option : groups.get(index)) {
            current.add(option);  // 加入当前选项
            generateCombinations(groups, current, results, index + 1);  // 递归处理下一组
            current.remove(current.size() - 1);  // 回溯，移除当前选项
        }
    }

    public static List<List<String>> parseAndGenerateCombinations(String expr, Map<String, String> bracketContentMap) {
        String[] andGroups = expr.split("\\+");
        List<List<String>> groups = new ArrayList<>();

        for (String group : andGroups) {
            // 获取括号内的内容或者直接处理字符串
            String content = bracketContentMap.getOrDefault(group, group);
            List<String> options = Arrays.asList(content.split("\\|"));  // 按照 | 分割获取选项
            groups.add(options);
        }

        // 生成排列组合
        List<List<String>> results = new ArrayList<>();
        generateCombinations(groups, new ArrayList<>(), results, 0);

        return results;
    }
    // 处理 AND 的表达式
    private static void handleAndExpression(String expr, Map<String, String> bracketContentMap, Set<Set<String>> andSets, Set<Set<String>> orSets) {
        String[] andGroups = expr.split("\\+");
        List<Set<String>> andCombinations = new ArrayList<>();
        List<Set<String>> orCombinations = new ArrayList<>();
        String realContent = "";
        // (A|B|C|D)+(a|b|c|d)+(1|2|3|4)
        // 全部进行排列组合
        for (String group : andGroups) {
            String content = bracketContentMap.get(group);
            realContent += content;
        }
        if(!realContent.contains("+")){
            List<List<String>> combinations = parseAndGenerateCombinations(expr, bracketContentMap);
            for (List<String> combination : combinations) {
                Set<String> strings = new HashSet<>(combination);
                orCombinations.add(strings);
            }
            orSets.addAll(orCombinations);
            return;
        }
        for (String group : andGroups) {
            if (group.startsWith("X")) {
                String content = bracketContentMap.get(group);
                if (content.contains("|")) {
                    // 如果括号内是 OR 关系，则处理 OR 集合
                    Set<Set<String>> tempOrSets = new HashSet<>();
                    parseWithParentheses(content, new HashSet<>(), tempOrSets);
                    orCombinations.addAll(tempOrSets);

                } else {
                    // 如果括号内是 AND 关系，直接加入 AND 集合
                    Set<String> set = new HashSet<>(Arrays.asList(content.split("\\+")));
                    andCombinations.add(set);
                }
            } else {
                // 处理括号外的 AND 集合
                Set<String> set = new HashSet<>(Arrays.asList(group.split("\\+")));
                andCombinations.add(set);
            }
        }

        // 判断是否存在 OR 组合
        if (orCombinations.isEmpty()) {
            andSets.addAll(andCombinations);
        } else {
            // 处理 AND + OR 组合排列
            combineAndOr(andCombinations, orCombinations, orSets);
        }
    }

    // 组合 AND 和 OR 集合
    private static void combineAndOr(List<Set<String>> andCombinations, List<Set<String>> orCombinations, Set<Set<String>> orSets) {
        for (Set<String> orSet : orCombinations) {
            for (String orElement : orSet) {
                Set<String> combination = new HashSet<>();
                for (Set<String> andSet : andCombinations) {
                    combination.addAll(andSet);
                }
                combination.add(orElement);
                orSets.add(combination);
            }
        }
    }

    IndexRotator indexRotator = new IndexRotator(Arrays.asList(0,1,2,3,4));

    @Override
    public List<MatchDistanceResp> matchKeywordByExpression(List<MatchDistanceReq> reqList) {
        List<Long> dataIds = reqList.stream().map(MatchDistanceReq::getDataID).collect(Collectors.toList());
        long start = System.currentTimeMillis();
        List<MatchDistanceResp> resps = reqList.stream()
                .map(req -> {
                    // 处理单个请求的逻辑
                    try {
                        return processSingleRequest(req);
                    } catch (Exception e) {
                        log.error("关键字表达式匹配逻辑出错：{},异常信息{}",JSONUtil.toJsonStr(reqList), e.getMessage());
                        e.printStackTrace();
                    }
                    return null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        long end = System.currentTimeMillis();
        log.info("关键字表达式一条消息匹配大小：{}，耗时：{}",reqList.size(),end-start);
        if(!resps.isEmpty()){
            log.info("关键字表达式匹配成功：{}",dataIds);
            // 匹配完成后发给推送队列
            String messageId = UUID.randomUUID().toString();
            Message pushDataMessage = MessageBuilder.withBody(JSONUtil.toJsonStr(resps).getBytes(StandardCharsets.UTF_8))
                    .setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)
                    .setMessageId(messageId)  // 设置 MessageId
                    .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                    .build();
            CorrelationData correlationData = new CorrelationData(messageId);
            rabbitTemplate.send(RabbitMqCon.DIRECT_EXCHANGE, RabbitMqCon.PUSH_MATCHED_DATA_KEY + indexRotator.getNextIndex(), pushDataMessage, correlationData);
        }
        return resps;
    }

//    private MatchDistanceResp processSingleRequest(MatchDistanceReq req) throws ExecutionException, InterruptedException {
//
//        MatchDistanceResp matchDistanceResp = new MatchDistanceResp();
//
//        String text = req.getTitle() + " " + req.getContent() + " " + req.getImageContent();
//
//        // 匹配关键字
//        List<Emit> expressionMatches = keywordIndex.match(text, "expression");
//
//        // 存储每组匹配的方案信息
//        Map<Long,Map<String, Set<Set<String>>>> matchedPlans = new HashMap<>();
//
//        long start = System.currentTimeMillis();
//
//        // 处理匹配
//        processMatches(expressionMatches, matchedPlans);
//
//        Map<Long, MatchByKeywordReq> keywordPlanMap = keywordIndex.keywordPlanMap;
//        // 只保留 matchedPlans 中的键
//        Map<Long, MatchByKeywordReq> filteredKeywordPlanMap = keywordPlanMap.entrySet().stream()
//                .filter(entry -> matchedPlans.containsKey(entry.getKey())) // 仅保留 matchedPlans 中的键
//                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
//
//        // 所有匹配到的方案 id 映射
//
//        List<PlanManagesItem> planManages = new ArrayList<>();
//        for (Long planId : filteredKeywordPlanMap.keySet()) {
//            MatchByKeywordReq keywordReq = filteredKeywordPlanMap.get(planId);
//            Map<String, Set<Set<String>>> typeMapKeywordMap = matchedPlans.getOrDefault(planId,new HashMap<>());
//            Set<Set<String>> andSets = typeMapKeywordMap.getOrDefault("andSets",new HashSet<>());
//            if(!andSets.isEmpty()){
//                // 处理and关系的
//                if (containsAllElementsInAllSets(text, andSets)) {
//                    // 全部包含则成功
//                    // 处理返回参数
//                    buildPlanManage(req, planManages, planId, andSets,new HashSet<>(), keywordReq);
//                    continue;
//                }
//            }
//            Set<Set<String>> orSets = typeMapKeywordMap.getOrDefault("orSets",new HashSet<>());
//            if(!orSets.isEmpty()){
//                // 处理or关系的
//                for (Set<String> orSet : orSets) {
//                    if(containsAllElements(text,orSet)){
//                        // 有任意一个全部包含则成功
//                        // 处理返回参数
//                        buildPlanManage(req, planManages, planId, new HashSet<>(),orSet, keywordReq);
//                        break;
//                    }
//                }
//            }
//        }
//
//        long end = System.currentTimeMillis();
//
//        log.info("关键字表达式单个数据匹配耗时：{}",end-start);
//        if (!planManages.isEmpty()){
//            buildResp(matchDistanceResp, req);
//            matchDistanceResp.setPlanManages(planManages);
//            return matchDistanceResp;
//        }
//        return null;
//
//    }



    private void buildPlanManage(MatchDistanceReq req, List<PlanManagesItem> planManages, Long planId, Set<Set<String>> andSets,
                                 Set<String> orSet, MatchByKeywordReq keywordReq) {
        PlanManagesItem item = new PlanManagesItem();
        item.setAgencyId(keywordReq.getAgencyID());
        item.setMonitorType(keywordReq.getMonitorType());
        item.setPlanManageId(planId);
        item.setKeyword(orSet.isEmpty() ? andSets.stream()
                .map(sets -> String.join(" ", sets)) // 将每个集合的元素用空格连接
                .collect(Collectors.joining(" ")) : String.join(" ", orSet)); // 用空格拼接关键词

        planManages.add(item);

    }

    public static boolean containsAllElementsInAllSets(String text, Set<Set<String>> andSets) {
        for (Set<String> andSet : andSets) {
            for (String element : andSet) {
                if (!text.contains(element)) {
                    return false; // 一旦找到不包含的元素，立即返回 false
                }
            }
        }
        return true; // 如果所有集合的所有元素都在文本中，返回 true
    }
    public static boolean containsAllElements(String text, Set<String> orSet) {
        for (String element : orSet) {
            if (!text.contains(element)) {
                return false; // 如果文本中不包含某个元素，返回false
            }
        }
        return true;
    }
    private void processMatches(List<Emit> matches, Map<Long,Map<String, Set<Set<String>>>> matchedPlans) {
        for (Emit emit : matches) {
            String keyword = emit.getKeyword();
            // 获取该关键词对应的方案ID集合
            Set<String> planIds = keywordIndex.getPlansByKeyword("expression",keyword);
            for (String planId : planIds) {
                // 拿到每个方案对应的 表达式解析信息
                Map<String, Set<Set<String>>> keywordSetByPlanId = keywordIndex.getKeywordSetByPlanId(planId);
                Long key = Long.valueOf(planId);
                matchedPlans.put(key, keywordSetByPlanId);
            }
        }
    }

    private MatchDistanceResp buildResp(MatchDistanceResp matchDistanceResp, MatchDistanceReq req) {
        matchDistanceResp.setAuthor(req.getAuthor());
        matchDistanceResp.setDataID(req.getDataID());
        if (StrUtil.isNotBlank(req.getImageContent())) {
            matchDistanceResp.setContent(req.getContent() + "图片内容:" +  req.getImageContent());
        }else {
            matchDistanceResp.setContent(req.getContent());
        }
        matchDistanceResp.setMediaLink(req.getMediaType());

        matchDistanceResp.setMediaType(0);
        if(StrUtil.isNotBlank(req.getPublishTime())){
            matchDistanceResp.setReleaseTime(req.getPublishTime().replace("T"," "));
        }
        matchDistanceResp.setSource(req.getSource());
        matchDistanceResp.setTitle(req.getTitle());
        matchDistanceResp.setWebsite(req.getSourceUrl());
        matchDistanceResp.setCoverPhoto(req.getVideoImage());
        matchDistanceResp.setVideoPath(req.getVideoUrl());
        matchDistanceResp.setNickname(req.getSourceSite());
        matchDistanceResp.setStickerID(req.getStickerID());
        return matchDistanceResp;
    }



    private MatchDistanceResp processSingleRequest(MatchDistanceReq req) throws ExecutionException, InterruptedException {
        MatchDistanceResp matchDistanceResp = new MatchDistanceResp();
        String text = req.getTitle() + " " + req.getContent() + " " + req.getImageContent();
        long s1 = System.currentTimeMillis();
        // 先执行一次Aho-Corasick匹配，获取包含所有关键词的结果
        List<Emit> expressionMatches = keywordIndex.match(text, "expression");

        long s2 = System.currentTimeMillis();

        log.info("关键字表达式匹配耗时：{}",s2-s1);

        // 使用Map缓存匹配结果，加快逻辑关系判断速度
        Map<String, Boolean> keywordMatched = new HashMap<>();
        for (Emit emit : expressionMatches) {
            keywordMatched.put(emit.getKeyword(), true);
        }

        // 构建倒排索引，方便通过关键词快速找到相关方案
        Map<Long, Map<String, Set<Set<String>>>> matchedPlans = new HashMap<>();
        processMatches(expressionMatches, matchedPlans);

        // 只保留 matchedPlans 中的键，便于接下来的逻辑判断
        Map<Long, MatchByKeywordReq> filteredKeywordPlanMap = keywordIndex.keywordPlanMap.entrySet().stream()
                .filter(entry -> matchedPlans.containsKey(entry.getKey()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

        List<PlanManagesItem> planManages = new ArrayList<>();
        long s3 = System.currentTimeMillis();

        log.info("关键字表达式处理耗时：{}",s3-s2);
        // 遍历每个方案，判断其关键词逻辑关系
//        for (Long planId : filteredKeywordPlanMap.keySet()) {
//            MatchByKeywordReq keywordReq = filteredKeywordPlanMap.get(planId);
//            Map<String, Set<Set<String>>> typeMapKeywordMap = matchedPlans.get(planId);
//
//            // andSets 逻辑判断
//            Set<Set<String>> andSets = typeMapKeywordMap.getOrDefault("andSets",new HashSet<>());
//            if(!andSets.isEmpty()){
//                boolean andMatched = true;
//                for (Set<String> andSet : andSets) {// [["你","地方","让人"],["同用途","调用","于"],["方法","供货商"],["沙发上","热度"]]
//                    for (String keyword : andSet) {
//                        if (!Boolean.TRUE.equals(keywordMatched.get(keyword))) {
//                            andMatched = false;
//                            break;
//                        }
//                    }
//                    if (!andMatched) break;
//                }
//
//                if (andMatched) {
//                    buildPlanManage(req, planManages, planId, andSets, new HashSet<>(), keywordReq);
//                }
//            }else {
//                // orSets 逻辑判断
//                Set<Set<String>> orSets = typeMapKeywordMap.getOrDefault("orSets",new HashSet<>());
//
//                for (Set<String> orSet : orSets) { // [["你","地方","让人"],["同用途","调用","于"],["方法","供货商"],["沙发上","热度"]]
//                    boolean allKeywordsMatched = true;
//                    for (String keyword : orSet) {
//                        if (!Boolean.TRUE.equals(keywordMatched.get(keyword))) {
//                            allKeywordsMatched = false;
//                            break;
//                        }
//                    }
//                    if (allKeywordsMatched) {
//                        buildPlanManage(req, planManages, planId, new HashSet<>(), orSet, keywordReq);
//                        break;
//                    }
//                }
//            }
//        }


//        Set<String> matchedKeywords = keywordMatched.entrySet().stream()
//                .filter(Map.Entry::getValue)
//                .map(Map.Entry::getKey)
//                .collect(Collectors.toSet());

        /*for (Long planId : filteredKeywordPlanMap.keySet()) {
            MatchByKeywordReq keywordReq = filteredKeywordPlanMap.get(planId);
            Map<String, Set<Set<String>>> typeMapKeywordMap = matchedPlans.get(planId);

            // 判断并处理 AND 逻辑集合
            Set<Set<String>> andSets = typeMapKeywordMap.getOrDefault("andSets", new HashSet<>());
            boolean andMatched = true;

            for (Set<String> andSet : andSets) {
                if (!matchedKeywords.containsAll(andSet)) {
                    andMatched = false;
                    break;
                }
            }
            if (andMatched && !andSets.isEmpty()) {
                buildPlanManage(req, planManages, planId, andSets, Collections.emptySet(), keywordReq);

                continue; // andSets 匹配成功则跳过 orSets 检查
            }

            // 处理 OR 逻辑集合
            Set<Set<String>> orSets = typeMapKeywordMap.getOrDefault("orSets", new HashSet<>());
            for (Set<String> orSet : orSets) {
                if (matchedKeywords.containsAll(orSet)) { // 只要有一个匹配
                    buildPlanManage(req, planManages, planId, Collections.emptySet(), orSet, keywordReq);
                    break;
                }
            }
        }*/
        for (Long planId : filteredKeywordPlanMap.keySet()) {
            MatchByKeywordReq keywordReq = filteredKeywordPlanMap.get(planId);
            Map<String, Set<Set<String>>> typeMapKeywordMap = matchedPlans.get(planId);

            // andSets 逻辑判断
            Set<Set<String>> andSets = typeMapKeywordMap.getOrDefault("andSets",new HashSet<>());
            if(!andSets.isEmpty()){
                boolean andMatched = true;
                for (Set<String> andSet : andSets) {// [["你","地方","让人"],["同用途","调用","于"],["方法","供货商"],["沙发上","热度"]]
                    for (String keyword : andSet) {
                        if (!Boolean.TRUE.equals(keywordMatched.get(keyword))) {
                            andMatched = false;
                            break;
                        }
                    }
                    if (!andMatched) break;
                }

                if (andMatched) {
                    buildPlanManage(req, planManages, planId, andSets, new HashSet<>(), keywordReq);
                }
            }else {
                // orSets 逻辑判断
                Set<Set<String>> orSets = typeMapKeywordMap.getOrDefault("orSets",new HashSet<>());

                for (Set<String> orSet : orSets) { // [["你","地方","让人"],["同用途","调用","于"],["方法","供货商"],["沙发上","热度"]]
                    boolean allKeywordsMatched = true;
                    for (String keyword : orSet) {
                        if (!Boolean.TRUE.equals(keywordMatched.get(keyword))) {
                            allKeywordsMatched = false;
                            break;
                        }
                    }
                    if (allKeywordsMatched) {
                        buildPlanManage(req, planManages, planId, new HashSet<>(), orSet, keywordReq);
                        break;
                    }
                }
            }
        }
        long s4 = System.currentTimeMillis();

        log.info("关键字表达式逻辑判断耗时：{}",s4-s3);
        if (!planManages.isEmpty()) {
            buildResp(matchDistanceResp, req);
            matchDistanceResp.setPlanManages(planManages);
            long s5 = System.currentTimeMillis();
            log.info("关键字表达式一条数据匹配耗时：{}",s5-s1);
            return matchDistanceResp;
        }

        return null;
    }






}


